package cn.sdc.sfw.util;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public final class TypeUtil {

	/*//test by lijunqiang
	public static void main(String[] args) {
		DecimalFormatSymbols symbols = new DecimalFormatSymbols();
		char decimalSep = symbols.getDecimalSeparator();
		char groupingSep = symbols.getGroupingSeparator();
		System.out.println(decimalSep);
		System.out.println(groupingSep);
		
		System.out.println(decimalNormalize("123,456.4587"));
	}
	*/
	
	/**
	 * Conversion to BigDecimal
	 * @param o
	 * @return
	 */
	public static BigDecimal toBigDecimal(Object o) {
		return toBigDecimal(o, null);
	}
	
	public static BigDecimal toBigDecimal(Object o, String pattern) {
		if (o == null) {
			return null;
		} else if (o instanceof BigDecimal) {
			return (BigDecimal) o;
		} else if (o instanceof Integer) {
			return new BigDecimal(((Integer) o).intValue());
		} else if (o instanceof String) {
			return new BigDecimal((String) o);
		} else if (o instanceof Double) {
			return new BigDecimal(((Double) o).doubleValue());
		} else if (o instanceof Long) {
			return new BigDecimal(((Long) o).longValue());
		} else if (o instanceof Short) {
			return new BigDecimal(((Short) o).shortValue());
		} else if (o instanceof Float) {
			return new BigDecimal(((Float) o).floatValue());
		} else if (o instanceof java.util.Date) {
			if (pattern != null) {
				return new BigDecimal(new SimpleDateFormat(pattern).format(o));
			} else {
				return new BigDecimal(((java.util.Date) o).getTime());
			}
		} else {
			return new BigDecimal(o.toString());
		}
	}	
	public static Long toLong(Object o) {
		return toLong(o, null);
	}
	
	public static Long toLong(Object o, String pattern) {
		if (o == null) {
			return null;
		} else if (o instanceof Long) {
			return (Long) o;
		} else if (o instanceof Number) {
			return new Long(((Number) o).longValue());
		} else if (o instanceof String) {
			return toLong((String) o);
		} else if (o instanceof java.util.Date) {
			if (pattern != null) {
				return new Long(new SimpleDateFormat(pattern).format(o));
			} else {
				return new Long(((java.util.Date) o).getTime());
			}
		} else if (o instanceof Boolean) {
			return ((Boolean) o).booleanValue() ? new Long(1) : new Long(0);
		} else {
			return toLong(o.toString());
		}
	}
	
	private static Long toLong(String s){
		return new Long(decimalNormalize(s));
	}
	
	private static String decimalNormalize(String s) {
		if (s == null || s.isEmpty()) {
			return null;
		}
		DecimalFormatSymbols symbols = new DecimalFormatSymbols();
		char groupingSep = symbols.getGroupingSeparator();
		/*
		char decimalSep = symbols.getDecimalSeparator();
		StringBuffer buf = new StringBuffer(2);
		for (int i = 0; i < s.length(); ++i) {
			char c = s.charAt(i);
			if (c == groupingSep) {
				continue;
			} else if (c == decimalSep) {
				c = '.';
			}
			buf.append(c);
		}
		*/
		return s.replace(String.valueOf(groupingSep), "");
	}
	
	public static BigInteger toBigInteger(Object o) {
		return toBigInteger(o, null);
	}
	
	public static BigInteger toBigInteger(Object o, String pattern) {
		if (o == null) {
			return null;
		} else if (o instanceof BigInteger) {
			return (BigInteger) o;
		} else {
			long l = toLong(o, pattern).longValue();
			return BigInteger.valueOf(l);
		}
	}
	
	public static byte[] toBinary(Object o) {
		if (o instanceof byte[]) {
			return (byte[])o;
		} else if (o == null) {
			return null;
		} else if (o instanceof String) {
			return ((String) o).getBytes();
		} else {
			throw new IllegalArgumentException(o.getClass().toString());
		}
	}
	
	public static Boolean toBoolean(Object o) {
		if (o == null) {
			return null;
		} else if (o instanceof Boolean) {
			return (Boolean) o;
		} else if (o instanceof Number) {
			int num = ((Number) o).intValue();
			return Boolean.valueOf(num != 0);
		} else if (o instanceof String) {
			String s = (String) o;
			if ("true".equalsIgnoreCase(s)) {
				return Boolean.TRUE;
			} else if ("false".equalsIgnoreCase(s)) {
				return Boolean.FALSE;
			} else if (s.equals("0")) {
				return Boolean.FALSE;
			} else {
				return Boolean.TRUE;
			}
		} else {
			return Boolean.TRUE;
		}
	}

	public static Byte toByte(Object o) {
		return toByte(o, null);
	}
	
	public static Byte toByte(Object o, String pattern) {
		if (o == null) {
			return null;
		} else if (o instanceof Byte) {
			return (Byte) o;
		} else if (o instanceof Number) {
			return new Byte(((Number) o).byteValue());
		} else if (o instanceof String) {
			return toByte((String) o);
		} else if (o instanceof java.util.Date) {
			if (pattern != null) {
				return new Byte(new SimpleDateFormat(pattern).format(o));
			} else {
				return new Byte((byte) ((java.util.Date) o).getTime());
			}
		} else if (o instanceof Boolean) {
			return ((Boolean) o).booleanValue() ? new Byte((byte) 1) : new Byte((byte) 0);
		} else {
			return toByte(o.toString());
		}
	}
	
	private static Byte toByte(String s) {
		return new Byte(decimalNormalize(s));
	}
	
	public static Date toDate(Object o) {
		return toDate(o, null);
	}
	
	public static Date toDate(Object o, String pattern) {
		if (o == null) {
			return null;
		} else if (o instanceof String) {
			return toDate((String) o, pattern);
		} else if (o instanceof Date) {
			return (Date) o;
		} else if (o instanceof Calendar) {
			return ((Calendar) o).getTime();
		} else {
			return toDate(o.toString(), pattern);
		}
	}
	
	public static Date toDate(String s, String pattern) {
		return toDate(s, pattern, Locale.getDefault());
	}
	
	public static Date toDate(String s, String pattern, Locale locale) {
		SimpleDateFormat sdf = DateUtil.getDateFormat(s, pattern, locale);
		try {
			return sdf.parse(s);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	public static java.sql.Date toSqlDate(Object o) {
		return toSqlDate(o,null);
	}
	
	public static java.sql.Date toSqlDate(Object o, String pattern) {
		if (o instanceof java.sql.Date) {
			return (java.sql.Date) o;
		} else {
			java.util.Date date = toDate(o, pattern);
			if (date != null) {
				return new java.sql.Date(date.getTime());
			} else {
				return null;
			}
		}
	}
	
	public static Double toDouble(Object o) {
		return toDouble(o, null);
	}
	
	public static Double toDouble(Object o, String pattern) {
		if (o == null) {
			return null;
		} else if (o instanceof Double) {
			return (Double) o;
		} else if (o instanceof Number) {
			return new Double(((Number) o).doubleValue());
		} else if (o instanceof String) {
			return toDouble((String) o);
		} else if (o instanceof java.util.Date) {
			if (pattern != null) {
				return new Double(new SimpleDateFormat(pattern).format(o));
			} else {
				return new Double(((java.util.Date) o).getTime());
			}
		} else {
			return toDouble(o.toString());
		}
	}
	
	private static Double toDouble(String s) {
		return new Double(decimalNormalize(s));
	}
	
	public static Float toFloat(Object o) {
		return toFloat(o, null);
	}
	
	public static Float toFloat(Object o, String pattern) {
		if (o == null) {
			return null;
		} else if (o instanceof Float) {
			return (Float) o;
		} else if (o instanceof Number) {
			return new Float(((Number) o).floatValue());
		} else if (o instanceof String) {
			return toFloat((String) o);
		} else if (o instanceof java.util.Date) {
			if (pattern != null) {
				return new Float(new SimpleDateFormat(pattern).format(o));
			} else {
				return new Float(((java.util.Date) o).getTime());
			}
		} else {
			return toFloat(o.toString());
		}
	}
	
	private static Float toFloat(String s) {
		return new Float(decimalNormalize(s));
	}
	
	public static Integer toInteger(Object o) {
		return toInteger(o, null);
	}
	
	public static Integer toInteger(Object o, String pattern) {
		if (o == null) {
			return null;
		} else if (o instanceof Integer) {
			return (Integer) o;
		} else if (o instanceof Number) {
			return new Integer(((Number) o).intValue());
		} else if (o instanceof String) {
			return toInteger((String) o);
		} else if (o instanceof java.util.Date) {
			if (pattern != null) {
				return new Integer(new SimpleDateFormat(pattern).format(o));
			} else {
				return new Integer((int) ((java.util.Date) o).getTime());
			}
		} else if (o instanceof Boolean) {
			return ((Boolean) o).booleanValue() ? new Integer(1) : new Integer(0);
		} else {
			return toInteger(o.toString());
		}
	}
	
	private static Integer toInteger(String s) {
		return new Integer(decimalNormalize(s));
	}
	
	public static Object convertPrimitiveNumber(Class type, Object o) {
		if (type == int.class) {
			Integer i = toInteger(o); 
			if (i != null) {
				return i;
			}
			return new Integer(0);
		} else if (type == double.class) {
			Double d = toDouble(o);
			if (d != null) {
				return d;
			}
			return new Double(0);
		} else if (type == long.class) {
			Long l = toLong(o);
			if (l != null) {
				return l;
			}
			return new Long(0);
		} else if (type == float.class) {
			Float f = toFloat(o);
			if (f != null) {
				return f;
			}
			return new Float(0);
		} else if (type == short.class) {
			Short s = toShort(o);
			if (s != null) {
				return s;
			}
			return new Short((short) 0);
		} else if (type == boolean.class) {
			Boolean b = toBoolean(o);
			if (b != null) {
				return b;
			}
			return Boolean.FALSE;
		}
		return o;
	}
	
	public static Object convertNumber(Class type, Object o) {
		if (type == Integer.class) {
			return toInteger(o);
		} else if (type == BigDecimal.class) {
			return toBigDecimal(o);
		} else if (type == Double.class) {
			return toDouble(o);
		} else if (type == Long.class) {
			return toLong(o);
		} else if (type == Float.class) {
			return toFloat(o);
		} else if (type == Short.class) {
			return toShort(o);
		} else if (type == BigInteger.class) {
			return toBigInteger(o);
		}
		return o;
	}
	

	public static Short toShort(Object o) {
		return toShort(o, null);
	}

	public static Short toShort(Object o, String pattern) {
		if (o == null) {
			return null;
		} else if (o instanceof Short) {
			return (Short) o;
		} else if (o instanceof Number) {
			return new Short(((Number) o).shortValue());
		} else if (o instanceof String) {
			return toShort((String) o);
		} else if (o instanceof java.util.Date) {
			if (pattern != null) {
				return new Short(new SimpleDateFormat(pattern).format(o));
			} else {
				return new Short((short) ((java.util.Date) o).getTime());
			}
		} else if (o instanceof Boolean) {
			return ((Boolean) o).booleanValue() ? new Short((short) 1)
					: new Short((short) 0);
		} else {
			return toShort(o.toString());
		}
	}

	private static Short toShort(String s) {
		return new Short(decimalNormalize(s));
	}
	
	public static String toString(Object value) {
		return toString(value, null);
	}

	public static String toString(Object value, String pattern) {
		if (value == null) {
			return null;
		} else if (value instanceof String) {
			return (String) value;
		} else if (value instanceof java.util.Date) {
			return toString((java.util.Date) value, pattern);
		} else if (value instanceof Number) {
			return toString((Number) value, pattern);
		} else if (value instanceof byte[]) {
			return value.toString();
		} else {
			return value.toString();
		}
	}

	public static String toString(Number value, String pattern) {
		if (value != null) {
			if (pattern != null) {
				return new DecimalFormat(pattern).format(value);
			} else {
				return value.toString();
			}
		} else {
			return null;
		}
	}

	public static String toString(java.util.Date value, String pattern) {
		if (value != null) {
			if (pattern != null) {
				return new SimpleDateFormat(pattern).format(value);
			} else {
				return value.toString();
			}
		} else {
			return null;
		}
	}
	
	public static Time toTime(Object o) {
		return toTime(o, null);
	}
	
	public static Time toTime(Object o, String pattern) {
		if (o instanceof Time) {
			return (Time) o;
		} else {
			java.util.Date date = toDate(o, pattern);
			if (date != null) {
				return new Time(date.getTime());
			} else {
				return null;
			}
		}
	}
	
	public static Timestamp toTimestamp(Object o) {
		return toTimestamp(o, null);
	}
	
	public static Timestamp toTimestamp(Object o, String pattern) {
		if (o instanceof Timestamp) {
			return (Timestamp) o;
		} else {
			Date date = toDate(o, pattern);
			if (date != null) {
				return new Timestamp(date.getTime());
			} else {
				return null;
			}
		}
	}
	
	public static Object toObject(Object o) {
		return o;
	}
	
	public static Object toObject(String s,Class clazz) {
		if(clazz.equals(String.class) || 
				clazz.equals(char.class) || 
				clazz.equals(Character.class)){
			return s;
		}
		if(s==null || s.isEmpty()){
			return null;
		}
		if(clazz.equals(Double.class) || 
				clazz.equals(double.class)){
			return toInteger(s);
		}
		if(clazz.equals(BigDecimal.class)){
			return toBigDecimal(s);
		}
		if(clazz.equals(BigInteger.class)){
			return toBigInteger(s);
		}
		if(clazz.equals(byte[].class)){
			return toBigDecimal(s);
		}
		if(clazz.equals(Boolean.class) || 
				clazz.equals(boolean.class)){
			return toBoolean(s);
		}
		if(clazz.equals(Byte.class) || 
				clazz.equals(byte.class)){
			return toByte(s);
		}
		if(clazz.equals(Date.class)){
			return toDate(s);
		}
		if(clazz.equals(Double.class) || 
				clazz.equals(double.class)){
			return toDouble(s);
		}
		if(clazz.equals(Float.class) || 
				clazz.equals(float.class)){
			return toFloat(s);
		}
		if(clazz.equals(Integer.class) || 
				clazz.equals(int.class)){
			return toInteger(s);
		}
		if(clazz.equals(Long.class) || 
				clazz.equals(long.class)){
			return toLong(s);
		}
		if(clazz.equals(Short.class) || 
				clazz.equals(short.class)){
			return toShort(s);
		}
		if(clazz.equals(Short.class) || 
				clazz.equals(short.class)){
			return toShort(s);
		}
		if(clazz.equals(Time.class)){
			return toTime(s);
		}
		if(clazz.equals(Timestamp.class)){
			return toTimestamp(s);
		}
		return s;
	}
}
